<template>
  <div class="page">
    <nav-bar title="详情页" @on-back="handleBack" @on-refresh="handleRefresh" />
    <div class="goods-images">
      <swiper
        v-if="goodsDetail.imgs.length"
        :slidesPerView="1"
        :pagination="{ clickable: true, type: 'bullets' }"
        :modules="modules"
        style="height: 220px"
      >
        <swiper-slide v-for="(cover, idx) in goodsDetail.imgs" :key="idx" style="height: 220px">
          <div class="flex" style="height: 220px">
            <img class="goods-cover" :src="cover" />
          </div>
        </swiper-slide>
      </swiper>
    </div>
    <div class="goods-info">
      <div class="title font-bold">{{ goodsDetail.title }}</div>
      <div class="price-info flex flex-start">
        <div class="origin-price">商品原价￥{{ goodsDetail.originalPrice }}</div>
        <div class="split"></div>
        <div class="goods-discounts flex flex-start">
          <div
            v-for="(discount, idx) in goodsDetail.discounts"
            class="goods-discount coupon"
            :key="idx"
          >
            <div class="coupon-type">{{ discount.label }}</div>
            <div class="coupon-text">{{ discount.value }}</div>
          </div>
        </div>
      </div>
      <div class="price flex flex-start">
        <div class="price-label">省心购会员价</div>
        <div class="price-value font-bold">￥{{ splitPrice.int || '' }}</div>
        <div class="price-float">{{ splitPrice.decimal || '' }}</div>
      </div>

      <div class="discounts flex flex-column">
        <div class="discount" v-for="(coupon, idx) in goodsDetail.coupons || []" :key="idx">
          <coupon-card :coupon="coupon" @on-click="handleBuy" />
        </div>
      </div>
    </div>
    <div v-if="recommendGoodsData.list.length" class="goods-recommend">
      <div class="goods-head font-500 flex flex-center">-猜你喜欢-</div>
      <div class="goods-list">
        <div class="goods-item" v-for="(goods, idx) in recommendGoodsData.list" :key="idx">
          <goods-card :goods="goods" />
        </div>
      </div>
    </div>
    <div class="bottom-box"></div>
    <div v-if="isValid && goodsDetail.goodsId" class="goods-buy flex flex-space">
      <div class="goods-price">
        <div class="vip-price flex flex-start">
          <div class="price-label">省心购会员价</div>
          <div class="price-value font-bold">￥{{ splitPrice.int || '' }}</div>
          <div class="price-float">{{ splitPrice.decimal || '' }}</div>
        </div>
        <div class="origin-price">商品原价￥{{ goodsDetail.originalPrice || '' }}</div>
      </div>
      <div class="goods-btn font-500 flex-shrink" @click="handleBuy">立即购买</div>
    </div>
    <jump-dialog ref="jumpDialogRef" :title="jumpTitle" :content="jumpContent" :list="jumpList" />
    <buy-dialog ref="buyDialogRef" />
  </div>
</template>
<script setup lang="ts">
import NavBar from '@/components/NavBar.vue'
import GoodsCard from '@/components/GoodsCard.vue'
import CouponCard from '@/components/CouponCard.vue'
import JumpDialog from '@/components/JumpDialog.vue'
import BuyDialog from '@/components/BuyDialog.vue'
import { Swiper, SwiperSlide } from 'swiper/vue'
import { Pagination } from 'swiper/modules'
import 'swiper/swiper-bundle.css'
import { computed, nextTick, onBeforeMount, onBeforeUnmount, onMounted, ref } from 'vue'
import { MallService } from '@/logics/services/mall'
import type { APICreateTaobaoGiftReqData } from '@/types/api/mall'
import type { GoodsDetail, GoodsItem, JumpDiscountItem } from '@/types/mall'
import { useRoute } from 'vue-router'
import type { PageListData } from '@/types'
import { AppService } from '@/logics/services/app'
import { MallAdapter } from '@/logics/adapters/mall'
import { AppError } from '@/utils/error'
import { AppErrorCode } from '@/helpers/constants/error_code'
import { browserBack, splitAmount } from '@/utils/utils'
let appService = new AppService()
let mallService = new MallService()
const route = useRoute()
const modules = ref([Pagination])
const isValid = ref(false) // 获取商品详情后再显示底部按钮
const jumpDialogRef = ref<InstanceType<typeof JumpDialog>>()
const buyDialogRef = ref<InstanceType<typeof BuyDialog>>()
const mobile = ref<string>('')
const goodsDetail = ref<GoodsDetail>({
  imgs: [],
  goodsId: '',
  title: '',
  price: '',
  originalPrice: 0,
  couponPrice: 0,
  commissionPrice: 0,
  coupons: [],
  discounts: [],
} as GoodsDetail)
const jumpTitle = ref('')
const jumpContent = ref('')
const jumpList = ref<JumpDiscountItem[]>([])
const hasRecommend = ref(false)
const recommendGoodsData = ref<PageListData<GoodsItem>>({
  page: 1,
  size: 10,
  loading: false,
  loadAll: false,
  list: [],
})
const splitPrice = computed(() => {
  if (goodsDetail.value.price) {
    return splitAmount(goodsDetail.value.price || '0')
  }
  return { int: '0', decimal: '.00' }
})
const queryMobile = async () => {
  const user = await appService.getAPPUserInfo()
  mobile.value = user.mobile
}
const queryGoodsDetailFromRoute = () => {
  const goods = route.query.goods as string
  if (!goods) return
  try {
    const parsedGoods = JSON.parse(goods) as GoodsItem
    if (parsedGoods.goodsId) {
      goodsDetail.value = MallAdapter.fromAPIGoodsToDetail(parsedGoods)
    }
  } catch (err) {
    console.error(err)
  }
}
const queryGoodsDetail = async () => {
  try {
    const goodsId = route.query.goodsId as string
    const detail = await mallService.getGoodsDetail({
      goodsId,
    })
    goodsDetail.value = detail
    isValid.value = true
  } catch (err) {
    console.error(err)
    isValid.value = false
  }
}
const queryRecommendGoods = async () => {
  try {
    const { loading, loadAll } = recommendGoodsData.value
    if (loading || loadAll) return
    recommendGoodsData.value.loading = true
    const params = {
      page: 1,
      page_size: 4,
      q: '',
    }
    const list = await mallService.getGoodsList(params)
    recommendGoodsData.value.list = list
    recommendGoodsData.value.loading = false
    recommendGoodsData.value.loadAll = true
  } catch (err) {
    recommendGoodsData.value.loading = false
    console.error(err)
  }
}
const handleBuy = async () => {
  try {
    if (!mobile.value || !goodsDetail.value.goodsId) {
      return
    }
    const params: APICreateTaobaoGiftReqData = {
      mobile: mobile.value,
      goodsId: goodsDetail.value.goodsId,
      title: goodsDetail.value.title,
    }
    const { discount, list } = MallAdapter.fromGoodsDetailToDiscounts(goodsDetail.value)
    jumpTitle.value = '正在跳转至天猫'
    jumpContent.value = `可省￥${discount.toFixed(2)}`
    jumpList.value = list
    jumpDialogRef.value?.openDialog()
    const gift = await mallService.createTaobaoGift(params)
    if (gift.sendUrl) {
      await appService.openAppBuyLink({
        type: 1,
        url: gift.sendUrl,
      })
    }
    jumpDialogRef.value?.closeDialog()
  } catch (err) {
    jumpDialogRef.value?.closeDialog()
    if (err instanceof AppError) {
      switch (err.code) {
        case AppErrorCode.NotSufficientFunds:
          buyDialogRef.value?.openDialog()
          break
        default:
          break
      }
    }
    console.error(err)
  }
}
const handleBack = () => {
  browserBack()
}
const handleRefresh = () => {
  setUp()
}
const setUp = async () => {
  document.documentElement.scrollTop = 0
  document.body.scrollTop = 0
  isValid.value = false
  nextTick(() => {
    queryMobile()
  })
  queryGoodsDetailFromRoute()
  nextTick(async () => {
    await queryGoodsDetail()
  })
  if (hasRecommend.value) {
    queryRecommendGoods()
  }
}
onMounted(() => {
  setUp()
})
onBeforeMount(() => {
  document.title = '详情页'
})
onBeforeUnmount(() => {
  goodsDetail.value = {} as GoodsDetail
  appService = null as unknown as AppService
  mallService = null as unknown as MallService
})
</script>
<style lang="scss" scoped>
.page {
  width: 100vw;
  overflow-x: hidden;
  background: #f5f5f5;
  box-sizing: border-box;
}
.goods-images {
  width: 100%;
  height: 220px;
  background: #fff;
  .goods-cover {
    height: 220px;
  }
}
.goods-info {
  position: relative;
  z-index: 1;
  padding: 16px 27px;
  box-sizing: border-box;
  background: #fff;
  margin-top: 12px;
  box-shadow: 0px 1px 1px 0px rgba(184, 184, 184, 0.17);
}
.goods-info {
  .title {
    line-height: normal;
    color: #000;
    font-size: 14px;
  }
  .price {
    line-height: 1;
    color: #ff5000;
    margin-top: 10px;
  }
  .price-info {
    line-height: 1;
    margin-top: 11px;
    .origin-price {
      font-size: 11px;
      color: #333;
    }
    .split {
      width: 1px;
      height: 12px;
      background: #9b9b9b;
      margin: 0 12px;
    }
  }
  .goods-discount + .goods-discount {
    margin-left: 12px;
  }
}
.discounts {
  margin-top: 20px;
  position: relative;
  z-index: 1;
  .discount {
    width: calc(100vw - 54px);
    height: 25vw;
    max-height: 120px;
  }
  .discount + .discount {
    margin-top: 10px;
  }
}
// 商品
.goods-recommend {
  padding: 0 12px;
  .goods-head {
    font-size: 12px;
    padding: 14px 0 8px;
    box-sizing: border-box;
  }
  .goods-list {
    display: flex;
    flex-wrap: wrap;
    .goods-item {
      width: 50%;
      margin-bottom: 6px;
    }
    .goods-item:nth-child(odd) {
      padding-right: 11px;
    }
  }
}
.goods-buy {
  position: fixed;
  left: 0;
  bottom: 0;
  height: 88px;
  line-height: 1;
  background: #fff;
  width: 100vw;
  box-shadow: 0px -1px 3px 0px rgba(164, 164, 164, 0.67);
  padding: 0 17px 0 31px;
  box-sizing: border-box;
  z-index: 999;
  .goods-price {
    .origin-price {
      margin-top: 12px;
      font-size: 11px;
      color: #333;
    }
  }
  .goods-btn {
    color: #f5f5f5;
    font-size: 14px;
    background: linear-gradient(90deg, #e32b1f, #fe5b3c);
    border-radius: 20px;
    padding: 14px 60px;
    box-sizing: border-box;
  }
}
.price-label {
  color: #f81112;
  font-size: 12px;
}
.price-value {
  color: #f81112;
  font-size: 14px;
}
.price-float {
  color: #f81112;
  font-size: 11px;
  margin-top: 3px;
}

.bottom-box {
  width: 100%;
  height: 108px;
}

::v-deep(.swiper-wrapper) {
  height: 220px;
}

::v-deep(.swiper-pagination-bullet-active) {
  background: #0b0b0b !important;
}
</style>
